package com.xwn.utils.core;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @Author duandw
 * @Date 2019/12/31 16:52
 **/
public class DateUtilsImpl extends org.apache.commons.lang3.time.DateUtils {
    private static String[] parsePatterns = new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public DateUtilsImpl() {
    }

    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    public static String formatDate(Date date, Object... pattern) {
        if (date == null) {
            return null;
        } else {
            String formatDate = null;
            if (pattern != null && pattern.length > 0) {
                formatDate = DateFormatUtils.format(date, pattern[0].toString());
            } else {
                formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
            }

            return formatDate;
        }
    }

    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String formatDateTime2(Date date) {
        return formatDate(date, "yyyyMMddHHmmss");
    }

    public static String formatDateTime3(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    public static String formatDateTime4(Date date) {
        return formatDate(date, "yyyy-MM");
    }

    public static String formatDateTime5(Date date) {
        return formatDate(date, "yyyyMMdd");
    }

    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str.toString(), parsePatterns);
            } catch (ParseException var2) {
                return null;
            }
        }
    }

    public static Date parseDate2(String str) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str, new String[]{"yyyyMMddHHmm"});
            } catch (ParseException var2) {
                return null;
            }
        }
    }

    public static Date parseDate3(String str) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str, new String[]{"yyyy-MM"});
            } catch (ParseException var2) {
                return null;
            }
        }
    }

    public static Date parseDate4(String str, String formateStr) {
        if (str != null && formateStr != null) {
            try {
                return parseDate(str, new String[]{formateStr});
            } catch (ParseException var3) {
                return null;
            }
        } else {
            return null;
        }
    }

    public static long pastDays(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 86400000L;
    }

    public static long pastHour(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 3600000L;
    }

    public static long pastMinutes(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 60000L;
    }

    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / 86400000L;
        long hour = timeMillis / 3600000L - day * 24L;
        long min = timeMillis / 60000L - day * 24L * 60L - hour * 60L;
        long s = timeMillis / 1000L - day * 24L * 60L * 60L - hour * 60L * 60L - min * 60L;
        long sss = timeMillis - day * 24L * 60L * 60L * 1000L - hour * 60L * 60L * 1000L - min * 60L * 1000L - s * 1000L;
        return (day > 0L ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    public static String formatDateTime2(long timeMillis) {
        long day = timeMillis / 86400000L;
        StringBuilder sb = new StringBuilder();
        sb.append(day > 0L ? day + "," : "");
        long hour = timeMillis / 3600000L - day * 24L;
        sb.append(hour < 10L ? "0" : "");
        sb.append(hour);
        long min = timeMillis / 60000L - day * 24L * 60L - hour * 60L;
        sb.append(min < 10L ? ":0" : ":");
        sb.append(min);
        long s = timeMillis / 1000L - day * 24L * 60L * 60L - hour * 60L * 60L - min * 60L;
        sb.append(s < 10L ? ":0" : ":");
        sb.append(s);
        long sss = timeMillis - day * 24L * 60L * 60L * 1000L - hour * 60L * 60L * 1000L - min * 60L * 1000L - s * 1000L;
        sb.append(".");
        sb.append(sss);
        return sb.toString();
    }

    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (double)((afterTime - beforeTime) / 86400000L);
    }

    public static String getDBTime(Date date) {
        if (date == null) {
            return "";
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(date);
        }
    }

    public static Date addDays(Date date, long days) {
        return new Date(date.getTime() + days * 1000L * 60L * 60L * 24L);
    }

    public static Date dateAddSecond(Date date, long second) {
        return new Date(date.getTime() + second * 1000L);
    }

    public static boolean isAfterGivenHours(Date date, long givenHour) {
        long pastMillSeconds = date.getTime() - truncateToDay(date).getTime();
        return pastMillSeconds > givenHour * 60L * 60L * 1000L;
    }

    public static boolean isBeforeGivenHours(Date date, long givenHour) {
        long pastMillSeconds = date.getTime() - truncateToDay(date).getTime();
        return pastMillSeconds < givenHour * 60L * 60L * 1000L;
    }

    public static Date truncateToDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar truncatedDate = Calendar.getInstance();
            truncatedDate.setTime(date);
            truncatedDate.set(11, 0);
            truncatedDate.set(12, 0);
            truncatedDate.set(13, 0);
            truncatedDate.set(14, 0);
            return truncatedDate.getTime();
        }
    }

    public static Date calcMetarTime(String day, String time, Date recvTime) {
        long eightHours = 28800L;
        Date utcRecvTime = dateAddSecond(recvTime, -eightHours);
        String metarTimeStr = formatDate(utcRecvTime, "yyyyMMdd") + time;

        Date utcSendTime;
        for(utcSendTime = parseDate2(metarTimeStr); !formatDate(utcSendTime, "dd").equals(day); utcSendTime = addDays(utcSendTime, -1)) {
            ;
        }

        return dateAddSecond(utcSendTime, eightHours);
    }

    public static long getDistanceOfTwoDate2(Date date1, Date date2) {
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        return time1 - time2 >= 0L ? time1 - time2 : time2 - time1;
    }

    public static int getDistanceOfTwoDate3(Date date1, Date date2) {
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        return (int)((time2 - time1) / 86400000L);
    }

    public static String getFirstDayOfMonthStr(String DateStr, String parseStr, String formateStr, int step) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(parseDate4(DateStr, parseStr));
        cal.add(2, step);
        cal.set(5, cal.getActualMinimum(5));
        return (new SimpleDateFormat(formateStr)).format(cal.getTime());
    }

    public static String getNextMonthFirstDayStr2(Date date) {
        return getFirstDayOfMonthStr2(date, 1);
    }

    public static String getMonthFirstDayStr2(Date date) {
        return getFirstDayOfMonthStr2(date, 0);
    }

    public static String getMonthLastDayStr(Date date) {
        return getLastDayOfMonthStr(date, 0);
    }

    public static String getFirstDayOfMonthStr2(Date date, int step) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(2, step);
        cal.set(5, cal.getActualMinimum(5));
        return formatDateTime3(cal.getTime());
    }

    public static String getLastDayOfMonthStr(Date date, int step) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(2, step);
        cal.set(5, cal.getActualMaximum(5));
        return formatDateTime3(cal.getTime());
    }

    public static Date getDateStepMonth(Date date, int step) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(2, step);
        return cal.getTime();
    }

    public static Date getFirstDayOfMonthDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, 1);

        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            return format.parse(format.format(cal.getTime()));
        } catch (ParseException var3) {
            var3.printStackTrace();
            return null;
        }
    }

    public static Date getLastDayOfMonthDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, 1);
        cal.add(2, 1);
        cal.add(5, -1);

        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
            return format.parse(format2.format(cal.getTime()) + " 23:59:59");
        } catch (ParseException var4) {
            var4.printStackTrace();
            return null;
        }
    }

    public static boolean isSameMonth(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        int month1 = cal.get(2);
        cal.setTime(date2);
        return month1 == cal.get(2);
    }

    public static Integer getDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.getActualMaximum(5);
    }

    public static Date getWeekFirstDay(Date date, Integer firstDay) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(firstDay);
        cal.setTime(date);
        cal.set(7, cal.getFirstDayOfWeek());
        return cal.getTime();
    }

    public static Integer getTimeBetweenTimeZone(Date date, String timeZone1, String timeZone2) {
        if (timeZone1.equals(timeZone2)) {
            return 0;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone(timeZone1));
            String fdaDateString = sdf.format(date);
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            try {
                Date fdaUtcDate = sdf.parse(fdaDateString);
                sdf.setTimeZone(TimeZone.getTimeZone(timeZone2));
                String qarDateString = sdf.format(date);
                sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date qarUtcDate = sdf.parse(qarDateString);
                return Long.valueOf((fdaUtcDate.getTime() - qarUtcDate.getTime()) / 60000L).intValue();
            } catch (ParseException var8) {
                var8.printStackTrace();
                return 0;
            }
        }
    }

    public static Date transDateBetweenTimeZone(Date date, String timeZone1, String timeZone2) {
        return T.DateUtils.addMinutes(date, getTimeBetweenTimeZone(date, timeZone1, timeZone2));
    }

    public static Date transDateFromLocalToSpecified(Date date, String timeZone) {
        if (T.StringUtils.isNoneBlank(new CharSequence[]{timeZone})) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
            String fdaDateString = sdf.format(date);
            sdf.setTimeZone(TimeZone.getDefault());

            try {
                return sdf.parse(fdaDateString);
            } catch (ParseException var5) {
                var5.printStackTrace();
            }
        }

        return date;
    }
}
